﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text;
using System.Threading;

namespace Powershell_ML
{
    public class PowerShell_Instance
    {
        public PowerShell_Instance()
        {
            try
            { 
            this.Output = new List<PSObject>();
            this.Config = RunspaceConfiguration.Create();
            PSSnapInException snapInException = new PSSnapInException();
            this.Config.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out snapInException);
            this.Runspaces = RunspaceFactory.CreateRunspace(this.Config);
            this.Runspaces.Open();
            }
            catch (Exception) { }
        }
        public PSObject Execute_Scripts(string commands)
        {
            var Output_Data = new List<PSObject>();
            var pipeline = this.Runspaces.CreatePipeline();
            pipeline.Commands.AddScript(commands,true);
            pipeline.Commands.Add("Out-String");
            Collection<PSObject> PSOutput = pipeline.Invoke();
            try
            {
                foreach (PSObject cmd in PSOutput)
                {
                    return cmd;
                }
                return null;
            }
            catch
            {
                return null;
            }
        }
        public List<PSObject> Execute_Command(Command commands)
        {
            var Output_Data = new List<PSObject>();
            var pipeline = this.Runspaces.CreatePipeline();
            Collection<PSObject> PSOutput = new Collection<PSObject>();
            ManualResetEvent syncEvent = new ManualResetEvent(false);
            pipeline.Commands.Add(commands);
            try
            {
                System.Threading.Thread Powershell_Commands = new System.Threading.Thread
                (delegate ()
                {
                    syncEvent.Set();
                    PSOutput = pipeline.Invoke();
                    foreach (PSObject cmd in PSOutput)
                    {
                        Output_Data.Add(cmd);
                    }
                    syncEvent.Close();
                });
                Powershell_Commands.Start();
                Powershell_Commands.Join();
                return Output_Data;
            }
            catch
            {
                return Output_Data;
            }
        }
        public PSObject Execute_Command_Once(Command commands)
        {
            try
            {
                this.Output = new List<PSObject>();
                this.Pipeline = this.Runspaces.CreatePipeline();
                this.Pipeline.Commands.Add(commands);
                Collection<PSObject> PSOutput = this.Pipeline.Invoke();
                foreach (PSObject cmd in PSOutput)
                {
                    return cmd;
                }
                return null;
            }
            catch(Exception ex)
            {
                return null;
            }


        }
        public Pipeline Pipeline
        {
            get;set;
        }
        public Runspace Runspaces
        {
            get;
            set;
        }
        public List<PSObject> Output
        {
            get;
            set;
        }
        public RunspaceConfiguration Config
        {
            get;
            set;
        }
        public PSSnapInException Exception
        {
            get;
            set;
        }
        public RunspacePool Pool
        {
            get;
            set;
        }

    }
}
